import { Types } from "gm";

type GM_Notification_O = (options: Types.Notification.Option) => void;

type GM_Notification_T = (
  text: Types.Notification.Option["text"],
  title?: Types.Notification.Option["title"],
  image?: Types.Notification.Option["image"],
  onclick?: (this: Types.Notification.Option) => void,
) => void;

interface GM_ScriptInfo {
  readonly description: string | null;
  readonly excludes: string[];
  readonly includes: string[];
  readonly matches: string[];
  readonly name: string;
  readonly namespace: string | null;
  readonly resources: Record<string, Types.Resource>;
  readonly runAt: "start" | "end" | "idle";
  readonly uuid: string;
  readonly version: string | null;
}

interface GM_Info {
  readonly script: GM_ScriptInfo;
  readonly scriptHandler: "Greasemonkey";
  readonly scriptMetaStr: string;
  readonly version: string;
}

interface GM_Object extends CM_Object {
  getResourceUrl(name: string): Promise<`blob:${string}`>;
  openInTab(url: string, loadInBackground?: boolean): void;
  registerMenuCommand(
    caption: string,
    commandFunc: () => void | Promise<void>,
    accessKey?: string,
  ): void;
  xmlHttpRequest(details: Types.Xhr.Details): void;
  notification: GM_Notification_O & GM_Notification_T;
  setClipboard(text: string): void;
  readonly info: GM_Info;
}

declare module "gm" {
  export const GM: GM_Object;
  export let unsafeWindow: unsafeWindow;
}
